package com.zqh.irmadscore.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.zqh.irmadscore.service.FailureItemService;
import com.zqh.irmadscore.service.FileDealService;
import com.zqh.irmadscore.mapper.FailureItemMapper;
import com.zqh.irmadscore.model.entity.FailureItem;
import com.zqh.irmadscore.model.entity.TestData;
import com.zqh.irmadscore.model.enums.AlertType;
import com.zqh.irmadscore.model.enums.TractAlertType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class FileDealServiceImpl implements FileDealService {

    // 文件存储路径（根据实际需求配置）
    private static final String UPLOAD_DIR = System.getProperty("user.dir") + "/src/main/resources/static/excel_file/";

    @Override
    public boolean uploadFile(MultipartFile file) throws Exception {

        if (file.isEmpty()) {
//            return Result.fail(ResultCodeEnum.FAIL.getCode(), "文件不能为空");
            throw new Exception("文件不能为空");
        }

        try {
            // 生成唯一文件名（避免重复）
            String originalFilename = file.getOriginalFilename();
            System.out.println(originalFilename);
//            String fileExtension = FileUtil.getSuffix(originalFilename);
//            String uniqueFileName = UUID.randomUUID() + "." + fileExtension;

            if (!FileUtil.isDirectory(UPLOAD_DIR)) {
                // 确保目录存在
                FileUtil.mkdir(UPLOAD_DIR);
            }

            // 保存文件（Hutool 封装写入方法）
            FileUtil.writeBytes(file.getBytes(), UPLOAD_DIR + originalFilename);

            return true;

        } catch (IOException e) {
            throw new Exception("文件上传失败：" + e.getMessage());
        }

    }

    @Override
    public Object downloadFile(String fileName) throws IOException {
        String safeFileName = FileUtil.getName(fileName);
        File file = Paths.get(UPLOAD_DIR, safeFileName + ".xlsx").toFile();

        if (!file.exists()) {
            return ResponseEntity.notFound().build();
        }

        // 设置文件资源
        Resource resource = new FileSystemResource(file);

        // 尝试确定文件的内容类型
        String contentType = Files.probeContentType(file.toPath());

        // 如果无法确定内容类型，默认使用 Excel 文件的 MIME 类型
        if (contentType == null) {
            contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        }

        var R = ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + safeFileName + ".xlsx\"")
                .body(resource);

        return R;
    }

    /**
     * 读取 Excel 文件并返回测试数据列表
     *
     * @param fileName 文件名，用于指定要读取的 Excel 文件
     * @return 包含测试数据的列表
     * @throws RuntimeException 如果文件不存在、文件为空或读取过程中发生错误
     */
    @Override
    public List<TestData> readExcel(String fileName) {
        // 构造安全的文件名，防止路径遍历等安全问题
        String safeFileName = FileUtil.getName(fileName);
        // 拼接文件路径
        String filePath = UPLOAD_DIR + safeFileName + ".xlsx";
//        System.out.println(filePath);

        try {
            // 通过 ClassPathResource 加载文件
            ClassPathResource resource = new ClassPathResource("static/excel_file/" + safeFileName
                    + ".xlsx");

            // 检查文件是否存在
            if (!resource.exists()) {
                throw new RuntimeException("文件不存在");
            }

            // 检查文件大小
            if (resource.contentLength() == 0) {
                throw new RuntimeException("文件为空");
            }

            // 读取 Excel
            try (ExcelReader reader = ExcelUtil.getReader(resource.getInputStream())) {
                List<TestData> list = new ArrayList<>();

                // 读取所有行数据（默认读取第一个 Sheet）
                List<List<Object>> rows = reader.read();

                Integer id = 0;
                for (List<Object> row : rows) {
                    // 跳过第一行（标题行）
                    if (id != 0) {
                        // 处理时间数据，去除前导空格
                        String time = row.get(1).toString().replaceFirst("^\\s+", "");

                        // 构建 TestData 对象
                        TestData testData = TestData
                                .builder()
                                .id(id)
                                .monitorType(row.get(0).toString())
                                .time(time)
                                .value(row.get(2).toString())
                                .build();
                        list.add(testData);
                    }
                    id++;
                }

                return list;
            }
        } catch (Exception e) {
            // 捕获并处理读取过程中的异常
            throw new RuntimeException("读取 Excel 失败: " + e.getMessage(), e);
        }
    }

    private final FailureItemMapper failureItemMapper;
    private final FailureItemService failureItemService;

    /**
     * 导入警报历史记录
     *
     * @param file 上传的文件
     * @return 导入结果
     * @throws Exception 如果导入过程中发生错误
     */
    @Override
    public boolean importAlertHistory(MultipartFile file) throws Exception {

        if (file.isEmpty()) {
//            return Result.fail(ResultCodeEnum.FAIL.getCode(), "文件不能为空");
            throw new Exception("文件不能为空");
        }
        // 读取 Excel
        try (ExcelReader reader = ExcelUtil.getReader(file.getInputStream())) {

            // 读取所有行数据（默认读取第一个 Sheet）
            List<List<Object>> rows = reader.read();
            int id = 0;
            List<FailureItem> failureItemList = new ArrayList<>();

            for (List<Object> row : rows) {
                // 跳过第一行（标题行）
                if (id != 0) {

                    String failureType = "";
                    double value = Double.parseDouble(String.valueOf((row.get(2))));

                    var tractAlertType = TractAlertType.getEnumByValue(row.get(0).toString());
                    System.out.println(tractAlertType);

                    if (ObjectUtil.isNull(tractAlertType)) continue;

                    if (value > tractAlertType.getRank1Value()
                            && value < tractAlertType.getRank2Value()) {
                        failureType = AlertType.ALERT_RANK1.getText();
                        FailureItem failureItem = FailureItem
                                .builder()
                                .failureType(failureType)
                                .failureTime(row.get(1).toString())
                                .tractName(row.get(0).toString())
                                .build();
                        failureItemList.add(failureItem);
                    } else if (value >= tractAlertType.getRank2Value()) {

                        failureType = AlertType.ALERT_RANK2.getText();
                        FailureItem failureItem = FailureItem
                                .builder()
                                .failureType(failureType)
                                .failureTime(row.get(1).toString())
                                .tractName(row.get(0).toString())
                                .build();
                        failureItemList.add(failureItem);
                    }


                }
                id++;
            }

            failureItemService.saveBatch(failureItemList);
            log.info("保存成功！！！");

        } catch (Exception e) {
            // 捕获并处理读取过程中的异常
            throw new RuntimeException("读取 Excel 失败: " + e.getMessage(), e);
        }


        return true;

    }
}
